﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enough.Lifecycle.Common
{

    public class Messenger
    {
        public delegate void MessageReceiver<T>(T message);

        private static Messenger _instance = new Messenger();
        public static Messenger Default { get { return _instance; } }

        private Dictionary<Type, List<object>> _actionsByType = new Dictionary<Type, List<object>>();

        //private Dictionary<Type, List<Action>> actionsByType = new Dictionary<Type, List<Action>>();

        public void Register<T>(Action<T> callback)
        {
            Type type = typeof(T);
            if (!_actionsByType.ContainsKey(type))
            {
                List<object> list = new List<object>();
                list.Add(callback);
                _actionsByType[type] = list;
            }
            else
            {
                List<object> list = _actionsByType[type];
                list.Add(callback);
            }
        }

        public void Deregister<T>(Action<T> callback)
        {
            Type type = typeof(T);
            if (_actionsByType.ContainsKey(type))
            {
                List<object> actions = _actionsByType[type];
                actions.Remove(callback);
                if (actions.Count == 0)
                {
                    _actionsByType.Remove(type);
                }
            }
            else
            {
                Debug.WriteLine("Warning: unable to deregister unknown action " + type);
            }
        }

        public void Send<T>(T message)
        {
            if (_actionsByType == null)
            {
                return;
            }
            Type t = typeof(T);
            if (_actionsByType.ContainsKey(t))
            {
                List<object> actions = _actionsByType[t];
                foreach (object actionObj in actions)
                {
                    Action<T> action = actionObj as Action<T>;
                    if (action != null)
                    {
                        action(message);
                    }
                }
            }
        }
    }
}
